#include "rewine.h"

#include "rewine/LoaderSingleton.hpp"
#include "rewine/impl/CCustomExport.hpp"

using std::string;

int
rewine_SetSymbol(
        const char *dll, const char *symbol, int bOverride,
        void *address) {
    string sDll(dll); lower_string(sDll);
    auto pExport = rewine::CCustomExport::create();
    pExport->setValue(address);
    auto pLib = rewine::g_Loader->getLibManager().get(sDll);
    pLib->setOverride(symbol, std::dynamic_pointer_cast<rewine::IExport>(pExport), bOverride != 0);
    return 0;
}

int
rewine_SetForwardSymbol(
        const char *dll, const char *symbol, int bOverride,
        const char *forwardToDll, const char *forwardToSymbol) {
    auto pForwarder = rewine::CCustomExport::create();
    if (rewine::g_Loader->getSymbolResolver().resolveAndBind(nullptr, forwardToDll, forwardToSymbol, -1, pForwarder->getValueSynchronizerRef(), false)) {
        string sDll(dll); lower_string(sDll);
        auto pLib = rewine::g_Loader->getLibManager().get(sDll);
        pLib->setOverride(symbol, std::dynamic_pointer_cast<rewine::IExport>(pForwarder), bOverride != 0);
        return 0;
    }
    return -1;
}

int
rewine_UnsetSymbol(
        const char *dll, const char *symbol, int bOverride) {
    string sDll(dll); lower_string(sDll);
    auto pLib = rewine::g_Loader->getLibManager().get(sDll);
    pLib->unsetOverride(symbol, bOverride != 0);
    return 0;
}
